﻿using SD.Commons.DataFilters;
using System;
using System.Linq;
using System.Data.Linq;

namespace SD.DataAccess
{
    [Serializable]
    public class HOrganizationDao
    {
        [NonSerialized] private readonly ServiceDBDataContext _context = new ServiceDBDataContext();

        /// <summary>
        /// Gets the list.
        /// </summary>
        /// <param name="filter">The filter.</param>
        /// <param name="sortType">Type of the sort.</param>
        /// <param name="startRowIndex">Start index of the row.</param>
        /// <param name="max">The max.</param>
        /// <returns></returns>
        public IQueryable<Organization> GetList(HOrganizationFilter filter, string sortType, int startRowIndex, int max)
        {
            IQueryable<Organization> data = from org in _context.Organizations
                                            select org;

            // 1. Filter by condition
            if (filter != null)
            {
                data = GetListQuery(data, filter);
            }

            // 2. Sorting
            data = GetListSort(data, sortType);

            // 3. Limit the rows
            if (startRowIndex != -1)
            {
                data = data.Skip(startRowIndex).Take(max);
            }

            //return data
            return data;
        }

        /// <summary>
        /// Gets the list sort.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <param name="sortType">Type of the sort.</param>
        /// <returns></returns>
        private static IQueryable<Organization> GetListSort(IQueryable<Organization> data, string sortType)
        {
            bool sortDescending = false;
            if (!string.IsNullOrEmpty(sortType))
            {
                string[] values = sortType.Split(' ');
                sortType = values[0];

                if (values.Length > 1)
                {
                    sortDescending = (values[1] == "DESC");
                }

                switch (sortType)
                {
                    case "OrganisationName":
                        data = sortDescending
                                   ? data.OrderByDescending(o => o.OrganizationName)
                                   : data.OrderBy(o => o.OrganizationName);
                        break;

                    case "HeadOfficeAddressLine1":
                        data = sortDescending
                                   ? data.OrderByDescending(o => o.Address.AddressLine)
                                   : data.OrderBy(o => o.Address.AddressLine);
                        break;

                    case "PostCode":
                        data = sortDescending
                                   ? data.OrderByDescending(o => o.Address.Postcode)
                                   : data.OrderBy(o => o.Address.Postcode);
                        break;

                    case "Contact":
                        data = sortDescending
                                   ? data.OrderByDescending(o => o.Contact.FirstName).ThenBy(o => o.Contact.Surname)
                                   : data.OrderBy(o => o.Contact.FirstName).ThenBy(o => o.Contact.Surname);
                        break;

                    case "IsActive":
                        data = sortDescending ? data.OrderByDescending(o => o.IsActive) : data.OrderBy(o => o.IsActive);
                        break;
                }
            }
            return data;
        }

        /// <summary>
        /// Gets the list query.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <param name="filter">The filter.</param>
        /// <returns></returns>
        private static IQueryable<Organization> GetListQuery(IQueryable<Organization> data, HOrganizationFilter filter)
        {
            //Filter by the beginning of the letters
            if (filter.BeginningLetters != null)
            {
                data =
                    data.Where(
                        org =>
                        filter.BeginningLetters.Contains(org.OrganizationName[0].ToString()));
            }

            //Filter by in-active & active Organisation
            if (!filter.IncludeInactive)
            {
                data = data.Where(o => o.IsActive);
            }
            return data;
        }

        /// <summary>
        /// Gets the list count.
        /// </summary>
        /// <param name="filter">The filter.</param>
        /// <returns></returns>
        public int GetListCount(HOrganizationFilter filter)
        {
            IQueryable<Organization> data = from org in _context.Organizations
                                            select org;
            return GetListQuery(data, filter).Count();
        }

        /// <summary>
        /// Gets the organisation by id.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns></returns>
        public Organization GetOrganizationById(int id)
        {
            Organization organisation = _context.Organizations.FirstOrDefault(o => o.OrganizationId == id);
            return organisation;
        }

        public bool UpdateStatus(int organizationId, bool active)
        {
            bool flag = false;
            var query = _context.Organizations.FirstOrDefault(c => c.OrganizationId == organizationId);
            if (query != null)
            {
                query.IsActive = active;
                _context.SubmitChanges();
                flag = true;
            }
            return flag;
        }
    }
}